/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

/*
 * ReferencesGui.java
 * @todo tout nettoyer!
 *
 * Created on 8 juil. 2011, 14:25:42
 */
package app.views;

import app.App;
import app.core.CategorieListModel;
import app.events.ReferenceListener;
import app.events.ReferenceSelectedListener;
import app.events.eventobjects.ReferenceAddedEvent;
import app.events.eventobjects.ReferenceDeletedEvent;
import app.events.eventobjects.ReferenceUpdatedEvent;
import app.models.Categorie;
import app.models.Reference;
import java.awt.BorderLayout;
import java.awt.Point;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.ArrayList;
import java.util.List;
import java.util.Vector;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JMenuItem;
import javax.swing.JPopupMenu;
import javax.swing.JScrollPane;
import javax.swing.JTextField;
import javax.swing.JToolBar;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;

/**
 *
 * @author PREVROMA
 */
public class ReferencesGui extends javax.swing.JPanel implements ReferenceListener, ActionListener {

    // ---------------------------------------------------------- PUBLIC VARS --
    // ------------------------------------------------------- PROTECTED VARS --
    protected List<ReferenceSelectedListener> refSelectedListeners =
            new ArrayList<ReferenceSelectedListener>();
    // --------------------------------------------------------- PRIVATE VARS --
    private Vector<String> fields;
    private List<Reference> references;
    private CategorieListModel listModel;
    private String selectedCategorie;
    private String strFilter = "";
    //Gui components        
    private JButton btSearch;
    private JScrollPane jScrollPane1;
    private JLabel lblRechercher;
    private JList listCategories;
    private SimpleTable<Reference> referencesTable;
    private JToolBar tbRecherche;
    private JTextField txtSearch;
    private JPopupMenu popMenu;
    private JMenuItem miEdit;
    private JMenuItem miDelete;
    private JMenuItem miSelect;

    /**
     * Constructor
     */
    public ReferencesGui() {
        initComponents();
    }

    /**
     * Add multiple references
     * @param refs 
     */
    public void setReferences(List<Reference> refs) {
        for (Reference ref : refs) {
            this.addReference(ref);
        }
    }

    /**
     * Add a single reference
     * @param ref 
     */
    public void addReference(Reference ref) {
        //Check if need to add category
        Categorie cat = ref.getCategorie();
        if (!listModel.contains(cat)) {
            listModel.addElement(cat);
        }
        references.add(ref);
        //if this element need to be displayed imediately
        if ("".equals(selectedCategorie) || cat.getLibelle().equals(selectedCategorie)) {
            referencesTable.addElement(ref);
        }
    }

    public void displayCategorie(String categorieLibelle) {
        if (!selectedCategorie.equals(categorieLibelle)) {
            List<Reference> refs = new ArrayList<Reference>();
            for (Reference ref : references) {
                String refCat = ref.getCategorie().getLibelle();
                if ("".equals(categorieLibelle)
                        || categorieLibelle.equals(refCat)) {
                    refs.add(ref);
                }
            }
            referencesTable.setElements(refs);
            selectedCategorie = categorieLibelle;
        }
    }

    /**
     * Update a reference
     * @param oldRef
     * @param newRef 
     */
    public void updateReference(Reference oldRef, Reference newRef) {
        
        Categorie cat = newRef.getCategorie();
        if (!listModel.contains(cat)) {
            listModel.addElement(cat);
        }
        
        int id = references.indexOf(oldRef);
        references.set(id, newRef);

        referencesTable.updateElement(oldRef, newRef);
    }

    /**
     * Remove a reference
     * @param ref 
     */
    public void removeReference(Reference ref) {
        throw new UnsupportedOperationException("Not implemented yet");
    }

    public Reference getSelectedReference() {
        return referencesTable.getSelectedElement();
    }

    /**
     * Filter references to match the given pattern
     * @param pat 
     */
    public void filter(String pat) {
        if (!strFilter.equals(pat)) {
            listCategories.setSelectedIndex(0);
            if ("".equals(pat)) {
                referencesTable.setElements(references);
            } else {
                List<Reference> refs = new ArrayList<Reference>();
                for (Reference r : references) {
                    boolean desMatch = (r.getDesignation().contains(pat));
                    boolean catMatch = (r.getCategorie().getLibelle().contains(pat));

                    if (desMatch || catMatch) {
                        refs.add(r);
                    }
                }

                referencesTable.setElements(refs);
            }
        }
    }

    public void onMouseClicked(MouseEvent e) {
        if (e.getButton() == MouseEvent.BUTTON3) {
            Point p = e.getPoint();
            int row = referencesTable.rowAtPoint(p);
            referencesTable.setSelectedRow(row);
            popMenu.show(referencesTable, e.getX(), e.getY() + 20);
        }
        if (e.getClickCount() == 2) {
            fireReferenceSelected(getSelectedReference());
        }
    }

    @Override
    public void onReferenceAdded(ReferenceAddedEvent rae) {
        addReference(rae.getReference());
    }

    @Override
    public void onReferenceDeleted(ReferenceDeletedEvent rde) {
        throw new UnsupportedOperationException("Not supported yet.");
    }

    @Override
    public void onReferenceUpdated(ReferenceUpdatedEvent rue) {
        updateReference(rue.getOldRef(), rue.getNewRef());
    }

    @Override
    public void actionPerformed(ActionEvent e) {
        Object source = e.getSource();
        if (source.equals(btSearch)) {
            filter(txtSearch.getText());
        } else if (source.equals(miSelect)) {
        } else if (source.equals(miEdit)) {
            //Edit
            Reference ref = getSelectedReference();
            if (ref == null) {
                App.displayMessage("Veuillez selectionner une référence à "
                        + "modifier svp!", App.MESSAGE_TYPE.ERROR);
                return;
            } else {
                ReferenceForm form = new ReferenceForm(ref);
                Reference newRef = form.showDialog();
                if (newRef != null) {
                    App.getInstance().getCatalogue().updateReference(ref, newRef);
                }
            }
        }
    }

    //---------------------------------------------------------------- EVENTS --
    /**
     * Propagate the reference selected event
     * @todo
     * @param ref 
     */
    void fireReferenceSelected(Reference ref) {
        for (ReferenceSelectedListener listener : refSelectedListeners) {
            listener.referenceSelected(ref);
        }
    }

    public void addReferenceSelectedListener(ReferenceSelectedListener listener) {
        refSelectedListeners.add(listener);
    }

    public void removeReferenceSelectedListener(ReferenceSelectedListener listener) {
        refSelectedListeners.remove(listener);
    }

    private void initComponents() {

        references = new ArrayList<Reference>();
        listModel = new CategorieListModel();

        tbRecherche = new JToolBar();
        lblRechercher = new JLabel();
        txtSearch = new JTextField();
        btSearch = new JButton();
        jScrollPane1 = new JScrollPane();
        listCategories = new JList();
        referencesTable = new SimpleTable<Reference>();

        //Popupmenu preparation
        popMenu = new JPopupMenu("Hello");
        miEdit = new JMenuItem("Editer", App.createIcon("resources/note_edit.png"));
        miEdit.addActionListener(this);
        popMenu.add(miEdit);
        miDelete = new JMenuItem("Supprimer", App.createIcon("resources/note_delete.png"));
        miDelete.addActionListener(this);
        popMenu.add(miDelete);
        miSelect = new JMenuItem("Selectionner", App.createIcon("resources/note_go.png"));
        miSelect.addActionListener(this);
        popMenu.add(miSelect);


        setLayout(new BorderLayout(5, 5));

        tbRecherche.setFloatable(false);

        lblRechercher.setText("Recherche une référence :");

        btSearch.setIcon(app.App.createIcon("resources/search.png"));
        btSearch.setText("");
        btSearch.setFocusable(true);
        btSearch.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);
        btSearch.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM);

        tbRecherche.add(lblRechercher);
        tbRecherche.add(txtSearch);
        tbRecherche.add(btSearch);

        add(tbRecherche, BorderLayout.PAGE_START);

        listCategories.setModel(listModel);
        jScrollPane1.setViewportView(listCategories);

        add(jScrollPane1, BorderLayout.WEST);
        add(referencesTable, BorderLayout.CENTER);

        btSearch.addActionListener(this);
        txtSearch.addKeyListener(new KeyAdapter() {

            @Override
            public void keyPressed(KeyEvent e) {
                filter(txtSearch.getText());
            }
        });

        listCategories.addListSelectionListener(new ListSelectionListener() {

            @Override
            public void valueChanged(ListSelectionEvent e) {
                if (e.getValueIsAdjusting()) {
                    if (listCategories.getSelectedIndex() == 0) {
                        displayCategorie("");
                    } else {
                        displayCategorie((String) listCategories.getSelectedValue());
                    }
                }
            }
        });
        listCategories.setSelectedIndex(0);
        selectedCategorie = "";

        fields = new Vector<String>();
        fields.add("Id");
        fields.add("Designation");
        fields.add("PxVenteTTC");
        fields.add("PxAchatHT");
        fields.add("Stock");
        fields.add("Categorie.Libelle");
        referencesTable.setHeaders(fields);
        referencesTable.addMouseListener(new MouseAdapter() {

            @Override
            public void mouseClicked(MouseEvent e) {
                onMouseClicked(e);
            }
        });

    }

    public static void main(String[] args) {
        JFrame f = new JFrame();
        f.getContentPane().add(new ReferencesGui());
        f.setVisible(true);
    }
}
